package cn.xp1997.shiro.x.filter;

import cn.xp1997.shiro.x.exception.ShiroTokenException;
import cn.xp1997.shiro.x.subject.SubjectFactoryX;
import cn.xp1997.shiro.x.token.TokenX;
import cn.xp1997.shiro.x.utils.ShiroUtil;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;


/**
 * 自定义拦截器
 * @author xp
 */

public class FilterX extends BasicHttpAuthenticationFilter {

    private String unauthorizedUrl;

    private String authorizationName;




    public void setUnauthorizedUrl(String unauthorizedUrl){
        this.unauthorizedUrl = unauthorizedUrl;
    }

    public String getUnauthorizedUrl(){
        return this.unauthorizedUrl;
    }

    public void setAuthorizationName(String name){
        this.authorizationName = name;
    }

    public String getAuthorizationName(){
        return this.authorizationName;
    }

    /**
     * 认证授权 认证或授权失败抛出异常 成功返回true
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue){


        //认证
        boolean isExecuted = false;
        try {
            //执行认证
            isExecuted = executeLogin(request, response);
        }catch (IncorrectCredentialsException e){
            if(getUnauthorizedUrl() != null){
                try {
                    WebUtils.issueRedirect(request, response, getUnauthorizedUrl());
                } catch (IOException ex) {
                    throw new IncorrectCredentialsException("error to redirect unauthorizedUrl");
                }
            }else{
                throw e;
            }
        }


        return isExecuted;
    }

    /**
     * 执行登录认证， 认证失败抛出异常
     */
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response){
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        //是否是未授权页面
        if(httpServletRequest.getRequestURI().equals(getUnauthorizedUrl())){
            return true;
        }
        String token = httpServletRequest.getHeader(getAuthorizationName());
        if(null == token || "".equals(token)){
            throw new ShiroTokenException("token missing");
        }

        //创建subjectX
        SubjectFactoryX subjectFactoryX = ShiroUtil.getSecurityManagerX().getSubjectFactoryX();
        subjectFactoryX.createSubjectX(token);

        TokenX tokenX = new TokenX(token);
        // 提交给realm进行登入，如果错误他会抛出异常并被捕获
        getSubject(request, response).login(tokenX);
        return true;
    }

}
